package com.siashan.unipay4j.ali.pay;

import com.alipay.api.AlipayApiException;
import com.alipay.api.internal.util.AlipaySignature;
import com.siashan.unipay4j.ali.AbstractAliPay;
import com.siashan.unipay4j.core.IPayConfig;
import com.siashan.unipay4j.core.Result;
import com.siashan.unipay4j.core.TradeStateEnum;
import com.siashan.unipay4j.core.pay.INotify;
import com.siashan.unipay4j.core.pay.PayResponse;
import com.siashan.unipay4j.core.util.EnumUtil;
import lombok.extern.slf4j.Slf4j;

import javax.servlet.http.HttpServletRequest;
import java.math.BigDecimal;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;

/**
 * 支付宝支付回调
 *
 * @author siashan
 * @since v1.0.1
 **/
@Slf4j
public class AliPayNotify extends AbstractAliPay implements INotify {

    public AliPayNotify(IPayConfig aliPaySet) {
        super(aliPaySet);
    }

    public AliPayNotify() {
        super();
    }

    /**
     * 回调
     *
     * @param request   request
     * @return 回调结果
     */
    @Override
    public Result<PayResponse> execNotify(HttpServletRequest request) {
        log.info("AliNotify::=> 请求到达");
        Map<String, String> params = extractRequestMap(request);
        // 验签状态
        boolean verifyResult;
        try {
            //计算得出通知验证结果
            verifyResult = AlipaySignature.rsaCheckV1(params, payConfig.getAlipayPublicKey(), payConfig.getCharset(), payConfig.getSignType());
        } catch (AlipayApiException e) {
            log.warn("AliNotify::=>回调时时发生异常", e);
            return Result.exception();
        }
        if (verifyResult) {
//            return Result.tradeSuccess(wrapperNotifyResponse(params));

            log.info("AliNotify::=> 支付状态：" + params.get("trade_status"));
            TradeStateEnum tradeState = EnumUtil.getIEnum(AliTradeStateEnum.class, params.get("trade_status")).getTradeState();
            if (TradeStateEnum.SUCCESS.equals(tradeState)) {
                log.info("AliNotify::=> 支付结果:成功");
                return Result.tradeSuccess(wrapperNotifyResponse(params));
            } else {
                log.info("AliNotify::=> 支付结果：未成功");
                return Result.tradeFail(tradeState.getValue(), tradeState.getDesp());
            }



        } else {
            log.warn("AliNotify::=>验签失败");
            return Result.invalidSign();
        }
    }

    /**
     * 回调成功，同步返回给支付平台的报文
     *
     * @return 成功报文
     */
    @Override
    public String successMsg() {
        return "success";
    }

    /**
     * 回调失败，同步返回给支付平台的报文
     *
     * @return 失败报文
     */
    @Override
    public String failMsg() {
        return "fail";
    }

    /**
     * 解析请求参数
     *
     * @param request request
     * @return 请求参数
     */
    private Map<String, String> extractRequestMap(HttpServletRequest request) {
        Map<String, String> params = new HashMap<>();
        Map requestParams = request.getParameterMap();
        for (Iterator iter = requestParams.keySet().iterator(); iter.hasNext(); ) {
            String name = (String) iter.next();
            String[] values = (String[]) requestParams.get(name);
            String valueStr = "";
            for (int i = 0; i < values.length; i++) {
                valueStr = (i == values.length - 1) ? valueStr + values[i]
                        : valueStr + values[i] + ",";
            }
            params.put(name, valueStr);
        }
        return params;
    }


    /**
     * 封装回调结果
     *
     * @param notifyParam  回调响应报文
     * @return 回调结果
     */
    private PayResponse wrapperNotifyResponse(Map<String, String> notifyParam) {
        PayResponse response = new PayResponse();
        TradeStateEnum tradeState = EnumUtil.getIEnum(AliTradeStateEnum.class, notifyParam.get("trade_status")).getTradeState();
        response.setTradeState(tradeState);
        response.setOutTradeNo(notifyParam.get("out_trade_no"));
        response.setTradeNo(notifyParam.get("trade_no"));
        response.setTotalAmount(new BigDecimal(notifyParam.get("total_amount")));
        return response;
    }


}
